package com.enation.app.javashop.core.shop.model.dto;

import com.enation.app.javashop.core.shop.model.vo.FixReceiveTimeVO;
import com.enation.app.javashop.core.shop.model.vo.ReceiveTimeVO;
import com.enation.app.javashop.core.trade.order.model.enums.ShipTypeEnum;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author JFeng
 * @date 2020/11/24 16:10
 */
@Data
public class ReceiveTimeCalDTO implements Serializable {

    private static final long serialVersionUID = 5739331716616201111L;

    //输入
    private FixTimeDispatchSetting fixTimeDispatchSetting;

    private FixTimeSection selectedTimeSection;

    // 输出
    private List<FixTimeSection> currentDayChoice;
    private List<FixTimeSection> postDayChoice;
    private String currentDayText;
    private String postDayText;

    private Long receiveTimeStamp;
    private String receiveTimeText;

    private LocalDate currentDay;
    private LocalDate postDay;

    private Integer receiveTimeType;


    private String defaultTimeText="";
    private  Integer defaultSeq=0;

    public ReceiveTimeCalDTO(FixTimeDispatchSetting fixTimeDispatchSetting) {
        this.fixTimeDispatchSetting = fixTimeDispatchSetting;
    }

    /**
     * 根据具体选择时间 计算送达时间
     * @return
     */
    public void calculateSelectedReceiveTime() {
        if (selectedTimeSection == null) {
            selectedTimeSection = fixTimeDispatchSetting.getDefaultTimeSection();
        }

        DateTimeFormatter dayFormatter = DateTimeFormatter.ofPattern("MM月dd日");
        LocalDate dispatchDay = selectedTimeSection.getReceiveTimeType() == 1 ? LocalDate.now() : postDay;
        Integer receiveTime = selectedTimeSection.getReceiveTime();

        if(receiveTimeText!=null){
            defaultTimeText = receiveTimeText + dispatchDay.format(dayFormatter) + "\u0009" + selectedTimeSection.getReceiveTimeText();
        }
        LocalTime localTime = LocalTime.of(receiveTime / 100 % 100, receiveTime % 100);

        LocalDateTime dispatchTime = LocalDateTime.of(dispatchDay, localTime);
        this.receiveTimeStamp = dispatchTime.toInstant(ZoneOffset.of("+8")).toEpochMilli() / 1000;
    }

    public void calculateSelectedReceiveTime(Integer receiveTimeSeq) {
        // 定时达送达时间
        List<FixTimeSection> timeSections = fixTimeDispatchSetting.getTimeSections();
        FixTimeSection targetTimeSection=null;
        for (FixTimeSection timeSection : timeSections) {
            if (receiveTimeSeq.equals(timeSection.getSeq())) {
                targetTimeSection=timeSection;
                break;
            }
        }
        if(targetTimeSection==null){
            targetTimeSection=fixTimeDispatchSetting.getDefaultTimeSection();
        }
        this.selectedTimeSection = targetTimeSection;
        this.receiveTimeType = targetTimeSection.getReceiveTimeType();
        calculateSelectedReceiveTime();
    }

    /**
     * 计算店铺配置 可选配送天  今天 明天 后天 几天后
     * TODO 【当日计算结果需要缓存】 整点需要删除更新 没半个小时刷新
     */
    public void kickOffExceptDay() {
        DateTimeFormatter dayFormatter = DateTimeFormatter.ofPattern("MM月dd日");
        LocalDate nowDay = LocalDate.now();
        int dayOfWeek = nowDay.getDayOfWeek().getValue();

        String today = "今天\u0009" + nowDay.format(dayFormatter);
        Integer plusDays = 1;

        ExceptDaySetting exceptDayOfWeek = fixTimeDispatchSetting.getExceptDayOfWeek();

        if (exceptDayOfWeek != null) {
            String stopDays = exceptDayOfWeek.getStopDays();
            Integer dispatchDay = exceptDayOfWeek.getDispatchDay();
            Integer isCurrent = exceptDayOfWeek.getIsCurrent();
            // 不发货 当日 【下次发货天】
            if (stopDays.contains("," + dayOfWeek + ",")) {
                currentDayChoice=new ArrayList<>();
                plusDays = isCurrent == 1 ? dispatchDay - dayOfWeek : (dispatchDay + 7) - dayOfWeek;
            }
            // 不发货 前一天 【今天和下次发货天】
            if (stopDays.contains("," + (dayOfWeek + 1) + ",")) {
                currentDayText = today;
                plusDays = isCurrent == 1 ? dispatchDay - dayOfWeek : (dispatchDay + 7) - dayOfWeek;
            }
        }

        receiveTimeText = plusDays == 1 ? "明天" : (plusDays == 2 ? "后天" : plusDays + "天后");

        // 正常发货日  【今日+明日】
        if (exceptDayOfWeek == null || ((!exceptDayOfWeek.getStopDays().contains("," + dayOfWeek + ",") && !exceptDayOfWeek.getStopDays().contains("," + (dayOfWeek + 1) + ",")))) {
            currentDayText = today;
        }
        postDayText = receiveTimeText + "\u0009" + nowDay.plusDays(plusDays).format(dayFormatter);

        postDay=nowDay.plusDays(plusDays);
    }


    public void filterTimeSections() {
        List<FixTimeSection> timeSections = fixTimeDispatchSetting.getTimeSections();

        if(CollectionUtils.isEmpty(timeSections)){
            return;
        }

        Integer nowTime = Integer.valueOf(LocalTime.now().getHour()*100 + LocalTime.now().getMinute());

        //筛选时间段-今日配送时间段
        currentDayChoice = timeSections.stream().filter(fixTimeSection -> fixTimeSection.getReceiveTimeType() == 1 && fixTimeSection.getEndOrderTime() > nowTime).collect(Collectors.toList());

        //筛选时间段-明日配送时间段
        postDayChoice = timeSections.stream().filter(fixTimeSection -> fixTimeSection.getReceiveTimeType() == 0).collect(Collectors.toList());
    }

    public ReceiveTimeVO transToReceiveTimeVO(String county,String shippingType) {

        List<FixReceiveTimeVO> fixReceiveTimeVOS = new ArrayList<>();

        ReceiveTimeVO receiveTimeVO = new ReceiveTimeVO();
        receiveTimeVO.setHasReceiveTime(false);

        if (!fixTimeDispatchSetting.getAreaSetting().contains(county) || shippingType==null || shippingType.equals(ShipTypeEnum.GLOBAL.name())) {
            this.calculateSelectedReceiveTime();
        }else {
            this.filterTimeSections();
        }

        if (!CollectionUtils.isEmpty(currentDayChoice) && StringUtils.isNotEmpty(currentDayText)) {
            FixTimeSection timeSection = currentDayChoice.get(0);
            defaultTimeText = currentDayText + "\u0009\u0009" + timeSection.getReceiveTimeText();
            defaultSeq = timeSection.getSeq();
            fixReceiveTimeVOS.add(new FixReceiveTimeVO(currentDayChoice, currentDayText));
            receiveTimeVO.setHasReceiveTime(true);
        }

        if (!CollectionUtils.isEmpty(postDayChoice) && StringUtils.isNotEmpty(postDayText)) {
            if (StringUtils.isEmpty(defaultTimeText)) {
                FixTimeSection timeSection = postDayChoice.get(0);
                defaultTimeText = postDayText + "\u0009\u0009" + timeSection.getReceiveTimeText();
                defaultSeq = timeSection.getSeq();
            }
            fixReceiveTimeVOS.add(new FixReceiveTimeVO(postDayChoice, postDayText));
            receiveTimeVO.setHasReceiveTime(true);
        }

        receiveTimeVO.setDefaultSeq(defaultSeq);
        receiveTimeVO.setDefaultTimeText(defaultTimeText);
        receiveTimeVO.setTimeSections(fixReceiveTimeVOS);
        receiveTimeVO.setPostDay(postDay);
        return receiveTimeVO;
    }
}
